#include <mips/regdef.h>
#include <sys/syscall.h>

# Programa que calcula y devuelve el maximo comun 
# divisor entre dos numeros ingresados por parametro.

# Uso de registros:
# 	$2 (v0)		almacenara el resultado.
#	$4 (a0)		contiene el primer parametro.
#	$5 (a1)		contiene el segundo parametro.
#	$8 (t0)		temporal.
#	$9 (t1)		temporal.
#	$10 (t2)	temporal.
#	$11 (t3)	temporal.
#	$12 (t4)	temporal.

	.globl 		mcm
	.ent 		mcm 2
mcm:

	# PIDE ESPACIO PARA EL STACK

	.frame		$fp, 32, ra
	subu		sp, sp, 32		# se trata de una funcion "non-leaf".
	.cprestore 24

	# GUARDA EL SAVED REGS AREA
	
	sw		ra, 24(sp)		# almacena el Return Adress (ra).
	sw		$fp, 20(sp)		# almacena el Frame Pointer ($fp).
	sw		gp, 16(sp)		# almacena el Global Pointer (gp).
	move		$fp, sp

	# GUARDA ARG BUILDING AREA
		
	sw		a0, 0(sp)		# almaceno $a0.
	sw		a1, 4(sp)		# almaceno $a1.
	move		$fp, sp
	.mask		0xD000000C,-4		# necesito guardar los registros $31, $30, $28, $5 y $4.

	# REALIZA EL LLAMADO A LA FUNCION DE DIVISOR

	jal		mcd			# llamada a la funcion del divisor ($a0 y $a1 ya contienen los numeros M y N).

	# RECUPERA EL SAVED REGS AREA

	lw		ra, 24(sp)		# recupera $ra.
	lw		$fp, 20(sp)		# recupera $fp.
	lw		gp, 16(sp)		# recupera $gp.

	# RECUPERA ARG BUILDING AREA

	lw		a0, 0(sp)		# recupera $a0.	
	lw		a1, 4(sp)		# recupera $a2.

	# CALCULA EL MULTIPLO

	move		t0, a0			# almacena M en el registro $t0.
	move		t1, a1			# almacena N en el registro $t1.

	move		t2, v0			# almacena el divisor (devuelto en $v0) en el registro $t2.
	multu		t0, t1			
	mflo		t3			# el resultado de M * N lo guarda en $t3.
	mfhi		t6			# el resultado del overflow lo guarda en $t6
	bne		t6, zero, overf		
	div		t3, t2	
	mflo		t4			# guarda la division en $t4.
	move		v0, t4			# finalmente almacena el resultado en el registro $v0.
	b		exit

overf:	add		v0, zero, zero
	
	# DESTRUYE EL STACK
	
exit:	addu		sp, sp, 32		# libera el stack.
	

	# REGRESA A LA RUTINA CALLEE

	j		ra

	.end 		mcm
